/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is Forte for Java, Community Edition. The Initial * Developer of the Original Code is Sun Microsystems, Inc. Portions * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved. */ package org.netbeans.modules.autoupdate; import java.io.*; import java.net.URLConnection; import java.text.MessageFormat; import java.util.jar.*; import java.util.zip.ZipEntry; import java.util.Iterator; import java.util.ArrayList; import java.util.Date; import java.util.ResourceBundle; import java.security.cert.Certificate; import java.security.cert.X509Certificate; import org.openide.util.NbBundle; import org.openide.NotifyDescriptor; import org.openide.TopManager; import org.openide.util.RequestProcessor; /** This class downloads modules and verifies the digital signatures * this class also copyies the downloaded modules. * @author phrebejk */ class Downloader extends Object { /** Resource bundle */ private static final ResourceBundle bundle = NbBundle.getBundle( Downloader.class ); /** The collection of modules for update */ private Updates updates; /** The update check progress panel */ ProgressDialog progressDialog; /** Set to true if the download was canceled by the user */ private volatile boolean downloadCanceled; /** Total size of the download */ private int downloadSize; /** KBytes downloaded */ private long totalDownloaded; /** Number of modules to downaload */ private long modulesCount; /** Shoud internet download be performed */ private boolean urlDownload; /** Extension of the distribution files */ private static final String NBM_EXTENSION = "nbm"; // NOI18N /** Wizard validator, enables the Next button in wizard */ private Wizard.Validator validator; /** Creates new Downloader */ public Downloader( Updates updates, ProgressDialog progressDialog, Wizard.Validator validator, boolean urlDownload ) { this.updates = updates; this.validator = validator; this.progressDialog = progressDialog; this.urlDownload = urlDownload; } void doDownload() { downloadCanceled = false; Runnable task = new Runnable () { public void run() { progressDialog.setLabelText( ProgressDialog.PARTIAL_LABEL, bundle.getString( "CTL_PreparingDownload_Label" ) ); downloadSize = getTotalDownloadSize(); if ( downloadCanceled ) return; downloadAll(); if ( downloadCanceled ) return; // SignVerifier.verifyAll( updates ); validator.setValid( true ); } }; RequestProcessor.postRequest( task ); } /** Total size of download in KBytes */ int getTotalDownloadSize( ) { long result = 0L; modulesCount = 0; Iterator it = updates.getModules().iterator(); while( it.hasNext() ) { ModuleUpdate mu = (ModuleUpdate)it.next(); if ( mu.isSelected() && !mu.isDownloadOK() ) { result += mu.getDownloadSize(); modulesCount++; } } return (int)(result / 1024); } /** Downloads the modules from web */ private void downloadAll() { if ( downloadCanceled ) return; progressDialog.setGaugeBounds( ProgressDialog.OVERALL_GAUGE, 0, downloadSize ); progressDialog.setGaugeValue( ProgressDialog.OVERALL_GAUGE, 0 ); progressDialog.setLabelText( ProgressDialog.OVERALL_LABEL, "" ); // NOI18N progressDialog.setGaugeValue( ProgressDialog.PARTIAL_GAUGE, 0 ); int currentModule = 0; totalDownloaded = 0; Iterator it = updates.getModules().iterator(); long start_time = System.currentTimeMillis(); while( it.hasNext() ) { if ( downloadCanceled ) return; ModuleUpdate mu = (ModuleUpdate)it.next(); if ( mu.isSelected() && !mu.isDownloadOK() ) { progressDialog.setGaugeValue( ProgressDialog.PARTIAL_GAUGE, 0 ); progressDialog.setLabelText( ProgressDialog.PARTIAL_LABEL, mu.getName() + " [" + (currentModule + 1) + "/" + modulesCount + "]" ); // NOI18N download( start_time, mu ); currentModule++; } } progressDialog.setGaugeValue( ProgressDialog.OVERALL_GAUGE, downloadSize ); String mssgTotal = MessageFormat.format( bundle.getString( "FMT_DownloadedTotal" ), new Object[] { new Integer( downloadSize ), new Integer( downloadSize ) } ); progressDialog.setLabelText( ProgressDialog.OVERALL_LABEL, mssgTotal ); } /** Downloads a .NBM file into download directory */ private void download( long start_time, ModuleUpdate moduleUpdate ) { // throws java.io.IOException { int moduleDownloaded = 0; int flen = 0; while ( true ) { // Retry loop try { URLConnection distrConnection = null; if ( urlDownload ) { distrConnection = moduleUpdate.getDistribution().openConnection(); flen = distrConnection.getContentLength(); } else { flen = (int)moduleUpdate.getDistributionFile().length(); } if ( downloadCanceled ) return; moduleDownloaded = 0; progressDialog.setGaugeBounds( ProgressDialog.PARTIAL_GAUGE, 0, flen / 1024 ); /* File distrFile = new File( moduleUpdate.getDistribution().getFile() ); File destFile = new File( Autoupdater.Support.getDownloadDirectory(), distrFile.getName() ); */ File destFile = getNBM( moduleUpdate ); BufferedInputStream bsrc; if ( urlDownload ) { bsrc = new BufferedInputStream( distrConnection.getInputStream() ); } else { bsrc = new BufferedInputStream( new FileInputStream( moduleUpdate.getDistributionFile() ) ); } BufferedOutputStream bdest = new BufferedOutputStream( new FileOutputStream( destFile ) ); int c; int i = 0; long time_old, time_new; time_old = System.currentTimeMillis(); try { while( ( c = bsrc.read() ) != -1 ) { bdest.write( c ); moduleDownloaded++; totalDownloaded++; time_new = System.currentTimeMillis(); if ( downloadCanceled ) return; if ( moduleDownloaded % 4096 == 0 /* && time_new - time_old > 999 */ ) { time_new = time_old; String mssgTotal = MessageFormat.format( bundle.getString( "FMT_DownloadedTotal" ), new Object[] { new Integer( (int)(totalDownloaded / 1024) ), new Integer( downloadSize ) } ); progressDialog.setGaugeValue( ProgressDialog.OVERALL_GAUGE, (int)(totalDownloaded / 1024) > downloadSize ? downloadSize : (int)( totalDownloaded / 1024 ) ); progressDialog.setLabelText( ProgressDialog.OVERALL_LABEL, mssgTotal ); /* progressDialog.setLabelText( ProgressDialog.PARTIAL_LABEL, (int)(moduleDownloaded / 1024) + "KB of " + ( flen / 1024 ) + " downloaded."); */ progressDialog.setGaugeValue( ProgressDialog.PARTIAL_GAUGE, moduleDownloaded / 1024 ); } } } finally { bsrc.close(); bdest.close(); } } catch ( IOException e ) { // Download failed String mssg = MessageFormat.format( bundle.getString( "FMT_DownloadFailed" ), new Object[] { moduleUpdate.getName() } ); NotifyDescriptor nd = new NotifyDescriptor.Confirmation ( mssg, bundle.getString( "CTL_DownloadFailed" ), NotifyDescriptor.YES_NO_CANCEL_OPTION ); TopManager.getDefault().notify( nd ); if ( nd.getValue().equals( NotifyDescriptor.YES_OPTION ) ) { totalDownloaded -= moduleDownloaded; // Dont't count lost bytes continue; // Retry } else if ( nd.getValue().equals( NotifyDescriptor.CANCEL_OPTION ) ) { downloadCanceled = true; // Stop whole download validator.setValid( true ); return; } // User selected not to download current module totalDownloaded -= moduleDownloaded; // Dont't count lost bytes downloadSize -= flen * 1024; if ( getNBM( moduleUpdate ).exists() ) getNBM( moduleUpdate ).delete(); return; } //progressDialog.setGaugeValue( ProgressDialog.PARTIAL_GAUGE, (int)(moduleUpdate.getDownloadSize() / 1024 ) ); progressDialog.setGaugeValue( ProgressDialog.PARTIAL_GAUGE, flen / 1024 + 10); moduleUpdate.setDownloadOK( true ); return; // The module downloaded O.K. } } void cancelDownload() { downloadCanceled = true; } static File getNBM( ModuleUpdate mu ) { //File distrFile = new File(mu.getDistributionFileName() ); //File destFile = new File( Autoupdater.Support.getDownloadDirectory(), distrFile.getName() ); File destFile = new File( Autoupdater.Support.getDownloadDirectory(), mu.getDistributionFilename() ); return destFile; } // Deletes all files in download directory static void deleteDownload() { File[] nbms = getNBMFiles(); for( int i = 0; i < nbms.length; i++ ) { nbms[i].delete(); } } private static File[] getNBMFiles() { File dirList[] = Autoupdater.Support.getDownloadDirectory().listFiles( new FilenameFilter() { public boolean accept( File dir, String name ) { return name.endsWith( NBM_EXTENSION ); } }); return dirList; } } /* * Log * 10 Gandalf 1.9 1/12/00 Petr Hrebejk i18n * 9 Gandalf 1.8 12/1/99 Petr Hrebejk Checkin signatures of * NBM files & automatic autoupdate check added * 8 Gandalf 1.7 11/12/99 Petr Hrebejk Bug fixes: Texts, Not * NetBeans patches, unselecting modules * 7 Gandalf 1.6 11/11/99 Petr Hrebejk Download bug fix * 6 Gandalf 1.5 11/8/99 Petr Hrebejk Install of downloaded * modules added, Licenses in XML * 5 Gandalf 1.4 10/22/99 Ian Formanek NO SEMANTIC CHANGE - Sun * Microsystems Copyright in File Comment * 4 Gandalf 1.3 10/11/99 Petr Hrebejk Version before Beta 5 * 3 Gandalf 1.2 10/10/99 Petr Hrebejk AutoUpdate made to * wizard * 2 Gandalf 1.1 10/8/99 Petr Hrebejk Next Develop version * 1 Gandalf 1.0 10/7/99 Petr Hrebejk * $ */